package com.freeman.cement.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.freeman.cement.entity.Camera;
import com.freeman.cement.entity.hikvision.HikResultObject;
import com.hikvision.artemis.sdk.ArtemisHttpUtil;
import com.hikvision.artemis.sdk.config.ArtemisConfig;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class hikiscUtil {
    /**
     * 请根据自己的appKey和appSecret更换static静态块中的三个参数. [1 host]
     * 如果你选择的是和现场环境对接,host要修改为现场环境的ip,https端口默认为443，http端口默认为80.例如10.33.25.22:443 或者10.33.25.22:80
     * appKey和appSecret请按照或得到的appKey和appSecret更改.
     * TODO 调用前先要清楚接口传入的是什么，是传入json就用doPostStringArtemis方法，下载图片doPostStringImgArtemis方法
     */
    static {
        /*ArtemisConfig.host = "192.168.0.150:443";// 代理API网关nginx服务器ip端口
        ArtemisConfig.appKey = "22008496";// 秘钥appkey
        ArtemisConfig.appSecret = "bcSI9cWX8L4akpw9V4s6";// 秘钥appSecret*/

        try {
            ArtemisConfig.host = ConfigUtil.readKey("hikiscHost");
            ArtemisConfig.appKey = ConfigUtil.readKey("hikiscAppKey");
            ArtemisConfig.appSecret = ConfigUtil.readKey("hikiscAppSecret");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 能力开放平台的网站路径
     * TODO 路径不用修改，就是/artemis
     */
    private static final String ARTEMIS_PATH = "/artemis";

    public static String doPostStringArtemis(String url, String jsonbody) {
        final String getCamsApi = ARTEMIS_PATH + url;
        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", getCamsApi);//根据现场环境部署确认是http还是https
            }
        };
        String result = ArtemisHttpUtil.doPostStringArtemis(path, jsonbody, null, null, "application/json", null);// post请求application/json类型参数
        System.out.println("doPostStringArtemis返回: " + result);
        return result;
    }

    public static Map<String, String> getConfig()
    {
        Map<String, String> map = new HashMap<>();
        map.put("host", ArtemisConfig.host );
        map.put("appKey", ArtemisConfig.appKey);
        map.put("appSecret", ArtemisConfig.appSecret);
        return map;
    }

    /**
     * 调用POST请求下载图片类型接口，这里以获取访客记录中的图片接口为例
     * https://open.hikvision.com/docs/a0a1a0a24701a00aa904f7b151f97410#f11f3208
     *
     * @return
     */
    public static String getPicUrl(String svrIndexCode, String picUri) {
       if(StringUtils.isNotBlank(svrIndexCode) && StringUtils.isNotBlank(picUri)) {
           JSONObject jsonBody = new JSONObject();
           jsonBody.put("svrIndexCode", svrIndexCode);
           jsonBody.put("picUri", picUri);
           String body = jsonBody.toJSONString();
           return doPostStringArtemis("/api/video/v1/events/picture", jsonBody.toJSONString());
       } else {
           return null;
       }
    }

    public static String getPicUrlByJsonStr(String json) {
        if (StringUtils.isNotBlank(json)) {
            return doPostStringArtemis("/api/video/v1/events/picture", json);
        } else {
            return null;
        }
    }

    /**
     * 分页获取区域列表
     * @param pageNo
     * @param pageSize
     * @return
     */
    public static String getRegionList(int pageNo, int pageSize) {
        if(pageNo > 0 && pageNo <= 1000 && pageSize > 0 && pageSize <= 1000) {
            JSONObject jsonBody = new JSONObject();
            jsonBody.put("pageNo", pageNo);
            jsonBody.put("pageSize", pageSize);
            String body = jsonBody.toJSONString();
            return doPostStringArtemis("/api/resource/v1/regions", jsonBody.toJSONString());
        } else {
            return null;
        }
    }

    /**
     * 根据区域获取下级资源列表v2
     * /api/irds/v2/resource/subResources
     * http://10.35.0.76:8182/sysmanage/hikisc/transport/api/irds/v2/resource/subResources?pageNo=1&pageSize=1000&resourceType=camera&regionIndexCode=a35da64c-4412-4b2a-a23c-8ead930dc426
     * @param regonIndexCode
     * @return
     */
    public static List<Camera> selectCameraByRegionIndexCode(String regonIndexCode) {
        if (StringUtils.isNotBlank(regonIndexCode)) {
            JSONObject jsonBody = new JSONObject();
            jsonBody.put("pageNo", 1);
            jsonBody.put("pageSize", 1000);
            jsonBody.put("resourceType", "camera");
            jsonBody.put("regionIndexCode", regonIndexCode);
            String result = doPostStringArtemis("/api/irds/v2/resource/subResources", jsonBody.toJSONString());
            if (StringUtils.isNotBlank(result)) {
                try {
                    HikResultObject ro = JSONObject.parseObject(result, HikResultObject.class);
                    if (ro != null && ro.getCode() != null && ro.getCode().equals("0") && ro.getData() != null) {
                        JSONObject data = JSONObject.parseObject(ro.getData());
                        Integer total = data.getInteger("total");
                        if (total != null && total > 0) {
                            JSONArray list = data.getJSONArray("list");
                            if (list != null && list.size() > 0) {
                                List<Camera> cameras = new ArrayList<>();
                                for (int i = 0; i < list.size(); i++) {
                                    Camera camera = new Camera();
                                    if (list.getJSONObject(i).containsKey("indexCode"))
                                        camera.setCameraIndexCode(list.getJSONObject(i).getString("indexCode"));
                                    if (list.getJSONObject(i).containsKey("name"))
                                        camera.setCameraName(list.getJSONObject(i).getString("name"));
                                    //if(list.getJSONObject(i).containsKey("regionIndexCode"))
                                    //    camera.setRegionIndexCode(list.getJSONObject(i).getString("regionIndexCode"));
                                    cameras.add(camera);
                                }
                                return cameras;
                            } else {
                                return null;
                            }
                        } else {
                            return null;
                        }
                    } else {
                        return null;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    //参见 OpenAPI安全认证库-JAVA版本_20200114201914 开发包
    /*public static String callPostImgStringApi() {
        *//**
         * http://10.33.47.50/api/visitor/v1/record/pictures
         * 根据API文档可以看出来，这是一个POST请求的Rest接口，而且传入的参数值为一个json
         * ArtemisHttpUtil工具类提供了doPostStringImgArtemis这个函数，一共六个参数在文档里写明其中的意思，因为接口是https，
         * 所以第一个参数path是一个hashmap类型，请put一个key-value，query为传入的参数，body为传入的json数据
         * 传入的contentType为application/json，accept不指定为null
         * header没有额外参数可不传,指定为null
         *
         *//*
        final String VechicleDataApi = ARTEMIS_PATH + "/api/video/v1/events/picture";
        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("http://", VechicleDataApi);
            }
        };

        JSONObject jsonBody = new JSONObject();
        jsonBody.put("svrIndexCode", "ee4cb4bc-8e3d-4784-85ba-366cf92de77e");
        jsonBody.put("picUri", "/pic?0d45959f6e7do-eel*11-d54oa=7562*1l9=0526*8888763=6116*pt==815**bs=c711*a585f2f0d-85498d-8pi158o=281d5=17e");
        String body = jsonBody.toJSONString();
        System.out.println("body: " + body);
        HttpResponse result = ArtemisHttpUtil.doPostStringImgArtemis(path, body, null, null, "application/json", null);
        try {
            HttpResponse resp = result;
            System.out.println("resp------>" + resp.toString());
            System.out.println("resp.getStatusLine().getStatusCode()------>" + resp.getStatusLine().getStatusCode());
            System.out.println("resp.getEntity()------>" + resp.getEntity().toString());
            System.out.println("resp.getEntity().getContent()------>" + resp.getEntity().getContent());
            if (200 == resp.getStatusLine().getStatusCode()) {
                HttpEntity entity = resp.getEntity();
                InputStream in = entity.getContent();
                savePicToDisk(in, "e:/", "test1.jpg");
                System.out.println("下载成功");
                return "下载成功";
            } else {
                System.out.println("下载出错");
                return "下载出错";
            }

        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }*/

    /**
     * 将图片写到 硬盘指定目录下
     *
     * @param in
     * @param dirPath
     * @param filePath
     */
    private static void savePicToDisk(InputStream in, String dirPath,
                                     String filePath) {
        try {
            File dir = new File(dirPath);
            if (dir == null || !dir.exists()) {
                dir.mkdirs();
            }

            //文件真实路径
            String realPath = dirPath.concat(filePath);
            File file = new File(realPath);
            if (file == null || !file.exists()) {
                file.createNewFile();
            }

            FileOutputStream fos = new FileOutputStream(file);
            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = in.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }
            fos.flush();
            fos.close();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
